home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / BasicSplitPaneDivider.java < prev    next >
Text File  |  1998-06-30  |  24KB  |  755 lines

  1. /*
  2.  * @(#)BasicSplitPaneDivider.java    1.17 98/02/02
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20.  
  21. package com.sun.java.swing.plaf.basic;
  22.  
  23. import java.awt.*;
  24. import java.awt.event.*;
  25. import com.sun.java.swing.*;
  26. import com.sun.java.swing.event.*;
  27. import com.sun.java.swing.plaf.*;
  28. import com.sun.java.swing.border.Border;
  29. import java.beans.*;
  30. import java.io.*;
  31.  
  32.  
  33. /**
  34.  * Divider used by BasicSplitPaneUI. Subclassers may wish to override
  35.  * paint to do something more interesting.
  36.  * The border effect is drawn in BasicSplitPaneUI, so if you don't like
  37.  * that border, reset it there.
  38.  * To conditionally drag from certain areas subclass mousePressed and
  39.  * call super when you wish the dragging to begin.
  40.  * <p>
  41.  * Warning: serialized objects of this class will not be compatible with
  42.  * future swing releases.  The current serialization support is appropriate
  43.  * for short term storage or RMI between Swing1.0 applications.  It will
  44.  * not be possible to load serialized Swing1.0 objects with future releases
  45.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  46.  * baseline for the serialized form of Swing objects.
  47.  *
  48.  * @version 1.17 02/02/98
  49.  * @author Scott Violet
  50.  */
  51. public class BasicSplitPaneDivider extends Container
  52.     implements PropertyChangeListener, Serializable
  53. {
  54.     /** Width or height of the divider based on orientation
  55.      * BasicSplitPaneUI adds two to this. */
  56.  
  57.     protected static final int ONE_TOUCH_SIZE = 5;
  58.     protected static final int ONE_TOUCH_OFFSET = 2;
  59.  
  60.     /** Handles mouse dragging message to do the actual dragging. */
  61.     protected DragController        dragger;
  62.     /** UI this instance was created from. */
  63.     protected BasicSplitPaneUI      splitPaneUI;
  64.     /** Size of the divider. */
  65.     protected int                   dividerSize = 0; // default - SET TO 0???
  66.     /** Divider that is used for noncontinuous layout mode. */
  67.     protected Component             hiddenDivider;
  68.     /** JSplitPane the receiver is contained in. */
  69.     protected JSplitPane            splitPane;
  70.     /** Handle of mouse events. */
  71.     protected MouseHandler          mouseHandler;
  72.     /** Orientation of the JSplitPane. */
  73.     protected int                   orientation;
  74.     /** Button for quickly toggling the left component. */
  75.     protected JButton               leftButton;
  76.     /** Button for quickly toggling the right component. */
  77.     protected JButton               rightButton;
  78.  
  79.     /** Cursor used for HORIZONTAL_SPLIT splitpanes. */
  80.     static final Cursor horizontalCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
  81.     /** Cursor used for VERTICAL_SPLIT splitpanes. */
  82.     static final Cursor verticalCursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
  83.     /** Default cursor. */
  84.     static final Cursor defaultCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  85.  
  86.  
  87.     /**
  88.       * Creates an instance of BasicSplitPaneDivider. Registers this
  89.       * instance for mouse events and mouse dragged events.
  90.       */
  91.     public BasicSplitPaneDivider(BasicSplitPaneUI ui) {
  92.     setLayout(new DividerLayout());
  93.     setBasicSplitPaneUI(ui);
  94.     orientation = splitPane.getOrientation();
  95.     setBackground(UIManager.getColor("SplitPane.background"));
  96.     }
  97.  
  98.     /**
  99.      * Sets the SplitPaneUI that is using the receiver.
  100.      */
  101.     public void setBasicSplitPaneUI(BasicSplitPaneUI newUI) {
  102.     if(splitPane != null) {
  103.         splitPane.removePropertyChangeListener(this);
  104.        if(mouseHandler != null) {
  105.            splitPane.removeMouseListener(mouseHandler);
  106.            splitPane.removeMouseMotionListener(mouseHandler);
  107.            mouseHandler = null;
  108.        }
  109.     }
  110.     splitPaneUI = newUI;
  111.     if(newUI != null) {
  112.         splitPane = newUI.getSplitPane();
  113.         if(splitPane != null) {
  114.         if(mouseHandler == null)
  115.             mouseHandler = new MouseHandler();
  116.         splitPane.addMouseListener(mouseHandler);
  117.         splitPane.addMouseMotionListener(mouseHandler);
  118.         splitPane.addPropertyChangeListener(this);
  119.         if(splitPane.isOneTouchExpandable())
  120.             oneTouchExpandableChanged();
  121.         }
  122.     }
  123.     else
  124.         splitPane = null;
  125.     }
  126.  
  127.     /**
  128.      * Returns the <code>SplitPaneUI</code> the receiver is currently
  129.      * in.
  130.      */
  131.     public BasicSplitPaneUI getBasicSplitPaneUI() {
  132.     return splitPaneUI;
  133.     }
  134.  
  135.     /**
  136.       * Sets the size of the divider to <code>newSize</code>. That is
  137.       * the width if the splitpane is <code>HORIZONTAL_SPLIT</code>, or
  138.       * the height of <code>VERTICAL_SPLIT</code>.
  139.       */
  140.     public void setDividerSize(int newSize) {
  141.     dividerSize = newSize;
  142.     }
  143.  
  144.     /**
  145.       * Returns the size of the divider, that is the width if the splitpane
  146.       * is HORIZONTAL_SPLIT, or the height of VERTICAL_SPLIT.
  147.       */
  148.     public int getDividerSize() {
  149.     return dividerSize;
  150.     }
  151.  
  152.     /**
  153.       * Returns dividerSize x dividerSize
  154.       */
  155.     public Dimension getPreferredSize() {
  156.     return new Dimension(getDividerSize(), getDividerSize());
  157.     }
  158.  
  159.     /**
  160.      * Property change event, presumably from the JSplitPane, will message
  161.      * updateOrientation if necessary.
  162.      */
  163.     public void propertyChange(PropertyChangeEvent e) {
  164.     if(e.getSource() == splitPane) {
  165.         if(e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY)) {
  166.         orientation = splitPane.getOrientation();
  167.         invalidate();
  168.         validate();
  169.         }
  170.         else if(e.getPropertyName().equals(JSplitPane.
  171.               ONE_TOUCH_EXPANDABLE_PROPERTY)) {
  172.         oneTouchExpandableChanged();
  173.         }
  174.     }
  175.     }
  176.  
  177.     /**
  178.       * Paints the divider.
  179.       */
  180.     public void paint(Graphics g) {
  181.       super.paint(g);
  182.     }
  183.  
  184.  
  185.     /**
  186.      * Messaged when the oneTouchExpandable value of the JSplitPane the
  187.      * receiver is contained in changes. Will create the
  188.      * <code>leftButton</code> and <code>rightButton</code> if they
  189.      * are null. invalidates the receiver as well.
  190.      */
  191.     protected void oneTouchExpandableChanged() {
  192.     if(splitPane.isOneTouchExpandable() && leftButton == null &&
  193.        rightButton == null) {
  194.         /* Create the left button and add an action listener to
  195.            expand/collapse it. */
  196.         leftButton = createLeftOneTouchButton();
  197.         if(leftButton != null)
  198.         leftButton.addActionListener(new LeftActionListener());
  199.  
  200.  
  201.         /* Create the right button and add an action listener to
  202.            expand/collapse it. */
  203.         rightButton = createRightOneTouchButton();
  204.         if(rightButton != null)
  205.         rightButton.addActionListener(new RightActionListener());
  206.  
  207.         if(leftButton != null && rightButton != null) {
  208.         add(leftButton);
  209.         add(rightButton);
  210.         }
  211.     }
  212.     invalidate();
  213.     validate();
  214.     }
  215.  
  216.     /**
  217.      * Creates and return an instance of JButton that can be used to
  218.      * collapse the left component in the split pane.
  219.      */
  220.     protected JButton createLeftOneTouchButton() {
  221.     JButton b = new JButton() {
  222.         public void setBorder(Border b) {
  223.         }
  224.         public void paint(Graphics g) {
  225.                 Dimension size = getSize();
  226.         if(splitPane != null) {
  227.             int[]          xs = new int[4];
  228.             int[]          ys = new int[4];
  229.             int            blockSize = Math.min(getDividerSize(),
  230.                             ONE_TOUCH_SIZE);
  231.  
  232.             if(orientation == JSplitPane.VERTICAL_SPLIT)
  233.             {
  234.             xs[0] = xs[3] = 0;
  235.             xs[1] = blockSize;
  236.             xs[2] = blockSize + blockSize;
  237.             ys[0] = ys[2] = ys[3] = blockSize;
  238.             ys[1] = 0;
  239.             }
  240.             else {
  241.             xs[0] = xs[2] = xs[3] = blockSize;
  242.             xs[1] = 0;
  243.             ys[0] = ys[3] = 0;
  244.             ys[1] = blockSize;
  245.             ys[2] = blockSize + blockSize;
  246.             }
  247.             g.setColor(Color.black);
  248.             g.fillPolygon(xs, ys, 4);
  249.         }
  250.         }
  251.     };
  252.         b.setFocusPainted(false);
  253.         b.setBorderPainted(false);
  254.         return b;
  255.     }
  256.  
  257.     /**
  258.      * Creates and return an instance of JButton that can be used to
  259.      * collapse the right component in the split pane.
  260.      */
  261.     protected JButton createRightOneTouchButton() {
  262.     JButton b = new JButton() {
  263.         public void setBorder(Border border) {
  264.         }
  265.         public void paint(Graphics g) {
  266.         if(splitPane != null) {
  267.             int[]          xs = new int[4];
  268.             int[]          ys = new int[4];
  269.             int            blockSize = Math.min(getDividerSize(),
  270.                             ONE_TOUCH_SIZE);
  271.  
  272.             if(orientation == JSplitPane.VERTICAL_SPLIT)
  273.             {
  274.              xs[0] = xs[3] = 0;
  275.             xs[1] = blockSize;
  276.             xs[2] = blockSize + blockSize;
  277.             ys[0] = ys[2] = ys[3] = 0;
  278.             ys[1] = blockSize;
  279.             }
  280.             else {
  281.             xs[0] = xs[2] = xs[3] = 0;
  282.             xs[1] = blockSize;
  283.             ys[0] = ys[3] = 0;
  284.             ys[1] = blockSize;
  285.             ys[2] = blockSize + blockSize;
  286.             }
  287.             g.setColor(Color.black);
  288.             g.fillPolygon(xs, ys, 4);
  289.         }
  290.         }
  291.     };
  292.         b.setFocusPainted(false);
  293.         b.setBorderPainted(false);
  294.         return b;
  295.     }
  296.  
  297.     /**
  298.       * Message to prepare for dragging. This messages the BasicSplitPaneUI
  299.       * with startDragging.
  300.       */
  301.     protected void prepareForDragging() {
  302.     splitPaneUI.startDragging();
  303.     }
  304.  
  305.     /**
  306.       * Messages the BasicSplitPaneUI with dragDividerTo that this instance
  307.       * is contained in.
  308.       */
  309.     protected void dragDividerTo(int location) {
  310.     splitPaneUI.dragDividerTo(location);
  311.     }
  312.  
  313.     /**
  314.       * Messages the BasicSplitPaneUI with finishDraggingTo that this instance
  315.       * is contained in.
  316.       */
  317.     protected void finishDraggingTo(int location) {
  318.     splitPaneUI.finishDraggingTo(location);
  319.     }
  320.  
  321.  
  322.     /**
  323.      * MouseHandler is responsible for converting mouse events
  324.      * (released, dragged...) into the appropriate DragController 
  325.      * methods.
  326.      * <p>
  327.      * Warning: serialized objects of this class will not be compatible with
  328.      * future swing releases.  The current serialization support is appropriate
  329.      * for short term storage or RMI between Swing1.0 applications.  It will
  330.      * not be possible to load serialized Swing1.0 objects with future releases
  331.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  332.      * baseline for the serialized form of Swing objects.
  333.      */
  334.     protected class MouseHandler extends MouseAdapter implements
  335.         MouseMotionListener, Serializable {
  336.     
  337.     /**
  338.      * Starts the dragging session by creating the appropriate instance
  339.      * of DragController.
  340.      */
  341.     public void mousePressed(MouseEvent e) {
  342.         if(e.getSource() == splitPane && dragger == null &&
  343.            splitPane.isEnabled()) {
  344.         Component            newHiddenDivider = splitPaneUI.
  345.                              getNonContinuousLayoutDivider();
  346.  
  347.         if(hiddenDivider != newHiddenDivider) {
  348.             if(hiddenDivider != null) {
  349.             hiddenDivider.removeMouseListener(this);
  350.             hiddenDivider.removeMouseMotionListener(this);
  351.             }
  352.             hiddenDivider = newHiddenDivider;
  353.             if(hiddenDivider != null) {
  354.             hiddenDivider.addMouseMotionListener(this);
  355.             hiddenDivider.addMouseListener(this);
  356.             }
  357.         }
  358.         if(splitPane.getLeftComponent() != null &&
  359.            splitPane.getRightComponent() != null) {
  360.             if(orientation == JSplitPane.HORIZONTAL_SPLIT)
  361.             dragger = new DragController(e);
  362.             else
  363.             dragger = new VerticalDragController(e);
  364.             if(!dragger.isValid())
  365.             dragger = null;
  366.             else {
  367.             prepareForDragging();
  368.             dragger.continueDrag(e);
  369.             }
  370.         }
  371.         e.consume();
  372.         }
  373.     }
  374.  
  375.     /**
  376.      * If dragg is not null it is messaged with completeDrag.
  377.      */
  378.     public void mouseReleased(MouseEvent e) {
  379.         if(dragger != null) {
  380.         if(e.getSource() == splitPane) {
  381.             dragger.completeDrag(e.getX(), e.getY());
  382.         }
  383.         else if(e.getSource() == hiddenDivider) {
  384.             Point       ourLoc = getLocation();
  385.             Point       hDividerLoc = hiddenDivider.getLocation();
  386.             int         ourX = e.getX() + hDividerLoc.x;
  387.             int         ourY = e.getY() + hDividerLoc.y;
  388.             
  389.             dragger.completeDrag(ourX, ourY);
  390.         }
  391.         dragger = null;
  392.         }
  393.         splitPane.setCursor(defaultCursor);
  394.         e.consume();
  395.     }
  396.  
  397.     //
  398.     // MouseMotionListener
  399.     //
  400.     /**
  401.      * If dragger is not null it is messaged with continueDrag.
  402.      */
  403.     public void mouseDragged(MouseEvent e) {
  404.         if(dragger != null) {
  405.         if(e.getSource() == splitPane) {
  406.             dragger.continueDrag(e.getX(), e.getY());
  407.         }
  408.         else if(e.getSource() == hiddenDivider) {
  409.             Point       ourLoc = getLocation();
  410.             Point       hDividerLoc = hiddenDivider.getLocation();
  411.             int         ourX = e.getX() + hDividerLoc.x;
  412.             int         ourY = e.getY() + hDividerLoc.y;
  413.             
  414.             dragger.continueDrag(ourX, ourY);
  415.         }
  416.         e.consume();
  417.         }
  418.     }
  419.  
  420.     /**
  421.      *  Resets the cursor based on the orientation.
  422.      */
  423.     public void mouseMoved(MouseEvent e) {
  424.         if(dragger != null)
  425.         return;
  426.  
  427.         int           eventX = e.getX();
  428.         int           eventY = e.getY();
  429.         Rectangle     bounds = getBounds();
  430.  
  431.         if(eventX >= bounds.x && (eventX < (bounds.x + bounds.width)) &&
  432.            eventY >= bounds.y && eventY < (bounds.y + bounds.height)) {
  433.         /* Reset the cursor. */
  434.         if(orientation == JSplitPane.HORIZONTAL_SPLIT) {
  435.             if(splitPane.getCursor() != horizontalCursor) {
  436.             splitPane.setCursor(horizontalCursor);
  437.             }
  438.         }
  439.         else if(splitPane.getCursor() != verticalCursor) {
  440.             splitPane.setCursor(verticalCursor);
  441.         }
  442.         }
  443.         else if(splitPane.getCursor() != defaultCursor) {
  444.         splitPane.setCursor(defaultCursor);
  445.         }
  446.     }
  447.     }
  448.  
  449.  
  450.     /**
  451.      * Handles the events during a dragging session for a
  452.      * HORIZONTAL_SPLIT orientated split pane. This continually
  453.      * messages dragDividerTo and then when done messages
  454.      * finishDraggingTo. When an instance is created it should be
  455.      * messaged with isValid() to insure that dragging can happen
  456.      * (dragging won't be allowed if the two views can not be resized).
  457.      * <p>
  458.      * Warning: serialized objects of this class will not be compatible with
  459.      * future swing releases.  The current serialization support is appropriate
  460.      * for short term storage or RMI between Swing1.0 applications.  It will
  461.      * not be possible to load serialized Swing1.0 objects with future releases
  462.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  463.      * baseline for the serialized form of Swing objects.
  464.      */
  465.     protected class DragController implements Serializable  {
  466.     /** Initial location of the divider. */
  467.     int                initialX;
  468.     /** Maximum and minimum positions to drag to. */
  469.     int                maxX, minX;
  470.     /** Initial location the mouse down happened at. */
  471.     int                offset;
  472.  
  473.     protected DragController(MouseEvent e) {
  474.         Component              leftC, rightC;
  475.         JSplitPane             splitPane = splitPaneUI.getSplitPane();
  476.         Insets                 insets = splitPane.getInsets();
  477.         int                    rightOffset;
  478.  
  479.         if(insets != null)
  480.         rightOffset = insets.right;
  481.         else
  482.         rightOffset = 0;
  483.         initialX = getLocation().x;
  484.         leftC = splitPane.getLeftComponent();
  485.         rightC = splitPane.getRightComponent();
  486.         if(leftC != null && rightC != null) {
  487.         minX = leftC.getMinimumSize().width +
  488.             leftC.getLocation().x;
  489.         maxX = Math.max(0, splitPane.getSize().width -
  490.                 (2 + getSize().width + rightOffset) -
  491.                 rightC.getMinimumSize().width);
  492.         if(maxX < minX)
  493.             minX = maxX = 0;
  494.         }
  495.         else
  496.         minX = maxX = 0;
  497.         offset = e.getX() - initialX;
  498.         if(offset < -1 || offset > getSize().width)
  499.         maxX = -1;
  500.     }
  501.  
  502.     /**
  503.       * Returns true if the dragging session is valid.
  504.       */
  505.     protected boolean isValid() {
  506.         return (maxX > 0);
  507.     }
  508.  
  509.     /**
  510.       * Returns the new position to put the divider at based on
  511.       * the passed in MouseEvent.
  512.       */
  513.     protected int positionForMouseEvent(MouseEvent e) {
  514.         int            newX;
  515.  
  516.         newX = Math.min(maxX, Math.max(minX, 
  517.                        e.getX() - offset));
  518.         return newX;
  519.     }
  520.  
  521.     /**
  522.      * Returns the x argument, since this is used for horizontal
  523.      * splits.
  524.      */
  525.     protected int getNeededLocation(int x, int y) {
  526.         int            newX;
  527.  
  528.         newX = Math.min(maxX, Math.max(minX, x - offset));
  529.         return newX;
  530.     }
  531.  
  532.     protected void continueDrag(int newX, int newY) {
  533.         dragDividerTo(getNeededLocation(newX, newY));
  534.     }
  535.  
  536.     /**
  537.       * Messages dragDividerTo with the new location for the mouse
  538.       * event.
  539.       */
  540.     protected void continueDrag(MouseEvent e) {
  541.         dragDividerTo(positionForMouseEvent(e));
  542.     }
  543.  
  544.     protected void completeDrag(int x, int y) {
  545.         finishDraggingTo(getNeededLocation(x, y));
  546.     }
  547.  
  548.     /**
  549.       * Messages finishDraggingTo with the new location for the mouse
  550.       * event.
  551.       */
  552.     protected void completeDrag(MouseEvent e) {
  553.         finishDraggingTo(positionForMouseEvent(e));
  554.     }
  555.     } // End of BasicSplitPaneDividier.DragController
  556.  
  557.  
  558.     /**
  559.       * Handles the events during a dragging session for a
  560.       * VERTICAL_SPLIT orientated split pane. This continually
  561.       * messages dragDividerTo and then when done messages
  562.       * finishDraggingTo. When an instance is created it should be
  563.       * messaged with isValid() to insure that dragging can happen
  564.       * (dragging won't be allowed if the two views can not be resized).
  565.       */
  566.     protected class VerticalDragController extends DragController {
  567.     /* DragControllers ivars are now in terms of y, not x. */
  568.  
  569.     protected VerticalDragController(MouseEvent e) {
  570.         super(e);
  571.         Component              leftC, rightC;
  572.         JSplitPane             splitPane = splitPaneUI.getSplitPane();
  573.         Insets                 insets = splitPane.getInsets();
  574.         int                    bottomOffset;
  575.  
  576.         if(insets != null)
  577.         bottomOffset = insets.bottom;
  578.         else
  579.         bottomOffset = 0;
  580.         initialX = getLocation().y;
  581.         leftC = splitPane.getLeftComponent();
  582.         rightC = splitPane.getRightComponent();
  583.         if(leftC != null && rightC != null) {
  584.         minX = leftC.getMinimumSize().height +
  585.             leftC.getLocation().y;
  586.         maxX = Math.max(0, splitPane.getSize().height -
  587.                 (2 + getSize().height + bottomOffset) -
  588.                 rightC.getMinimumSize().height);
  589.         if(maxX < minX)
  590.             minX = maxX = 0;
  591.         }
  592.         else
  593.         minX = maxX = 0;
  594.         offset = e.getY() - initialX;
  595.         if(offset < -1 || offset > getSize().height)
  596.         maxX = -1;
  597.     }
  598.  
  599.     /**
  600.      * Returns the y argument, since this is used for vertical
  601.      * splits.
  602.      */
  603.     protected int getNeededLocation(int x, int y) {
  604.         int            newY;
  605.  
  606.         newY = Math.min(maxX, Math.max(minX, y - offset));
  607.         return newY;
  608.     }
  609.  
  610.     /**
  611.       * Returns the new position to put the divider at based on
  612.       * the passed in MouseEvent.
  613.       */
  614.     protected int positionForMouseEvent(MouseEvent e) {
  615.         int            newY;
  616.  
  617.         newY = Math.min(maxX, Math.max(minX, 
  618.                        e.getY() - offset));
  619.         return newY;
  620.     }
  621.  
  622.     } // End of BasicSplitPaneDividier.VerticalDragController
  623.  
  624.  
  625.     /**
  626.      * Used to layout a BasicSplitPaneDivider. Layout for the divider
  627.      * involves appropraitely moving the left/right buttons around.
  628.      * <p>
  629.      * Warning: serialized objects of this class will not be compatible with
  630.      * future swing releases.  The current serialization support is appropriate
  631.      * for short term storage or RMI between Swing1.0 applications.  It will
  632.      * not be possible to load serialized Swing1.0 objects with future releases
  633.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  634.      * baseline for the serialized form of Swing objects.
  635.      */
  636.     protected class DividerLayout implements LayoutManager, Serializable {
  637.     public void layoutContainer(Container c) {
  638.         if(leftButton != null && rightButton != null &&
  639.            c == BasicSplitPaneDivider.this) {
  640.         if(splitPane.isOneTouchExpandable()) {
  641.             int          blockSize = Math.min(getDividerSize(),
  642.                               ONE_TOUCH_SIZE);
  643.  
  644.             if(orientation == JSplitPane.VERTICAL_SPLIT) {
  645.             int          y = (c.getSize().height - blockSize) / 2;
  646.  
  647.             leftButton.setBounds(ONE_TOUCH_OFFSET, y,
  648.                          blockSize * 2, blockSize);
  649.             rightButton.setBounds(2 * ONE_TOUCH_OFFSET +
  650.                           ONE_TOUCH_SIZE * 2, y,
  651.                           blockSize * 2, blockSize);
  652.             }
  653.             else {
  654.             int          x = (c.getSize().width - blockSize) / 2;
  655.  
  656.             leftButton.setBounds(x, ONE_TOUCH_OFFSET,
  657.                          blockSize, blockSize * 2);
  658.             rightButton.setBounds(x, 2 * ONE_TOUCH_OFFSET +
  659.                           ONE_TOUCH_SIZE * 2, blockSize,
  660.                           blockSize * 2);
  661.             }
  662.         }
  663.         else {
  664.             leftButton.setBounds(-5, -5, 1, 1);
  665.             rightButton.setBounds(-5, -5, 1, 1);
  666.         }
  667.         }
  668.     }
  669.     public Dimension minimumLayoutSize(Container c) {
  670.         return new Dimension(0,0);
  671.     }
  672.     public Dimension preferredLayoutSize(Container c) {
  673.         return new Dimension(0, 0);
  674.     }
  675.     public void removeLayoutComponent(Component c) {}
  676.     public void addLayoutComponent(String string, Component c) {}
  677.     } // End of class BasicSplitPaneDivider.DividerLayout
  678.  
  679.  
  680.     /**
  681.      * Listener for move-left events.
  682.      * <p>
  683.      * Warning: serialized objects of this class will not be compatible with
  684.      * future swing releases.  The current serialization support is appropriate
  685.      * for short term storage or RMI between Swing1.0 applications.  It will
  686.      * not be possible to load serialized Swing1.0 objects with future releases
  687.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  688.      * baseline for the serialized form of Swing objects.
  689.      */
  690.     private class LeftActionListener implements ActionListener, Serializable
  691.     {
  692.     public void actionPerformed(ActionEvent e) {
  693.         Insets       insets = splitPane.getInsets();
  694.         int          currentLoc;
  695.  
  696.         currentLoc = splitPane.getDividerLocation();
  697.         currentLoc += splitPaneUI.getDividerBorderSize();
  698.         if(orientation == JSplitPane.VERTICAL_SPLIT) {
  699.         if(currentLoc >= (splitPane.getHeight() -
  700.                   insets.bottom - getDividerSize()))
  701.             splitPane.setDividerLocation(splitPane.
  702.                          getLastDividerLocation());
  703.         else
  704.             splitPane.setDividerLocation(0);
  705.         }
  706.         else {
  707.         if(currentLoc >= (splitPane.getWidth() -
  708.                   insets.right - getDividerSize()))
  709.             splitPane.setDividerLocation(splitPane.
  710.                          getLastDividerLocation());
  711.         else
  712.             splitPane.setDividerLocation(0);
  713.         }
  714.     }
  715.     } // End of class BasicSplitPaneDivider.LeftActionListener
  716.  
  717.  
  718.     /**
  719.      * Listener for move-right events.
  720.      * <p>
  721.      * Warning: serialized objects of this class will not be compatible with
  722.      * future swing releases.  The current serialization support is appropriate
  723.      * for short term storage or RMI between Swing1.0 applications.  It will
  724.      * not be possible to load serialized Swing1.0 objects with future releases
  725.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  726.      * baseline for the serialized form of Swing objects.
  727.      */
  728.     private class RightActionListener implements ActionListener, Serializable
  729.     {
  730.     public void actionPerformed(ActionEvent e) {
  731.         Insets       insets = splitPane.getInsets();
  732.         int          currentLoc;
  733.  
  734.         currentLoc = splitPane.getDividerLocation();
  735.         currentLoc -= splitPaneUI.getDividerBorderSize();
  736.         if(orientation == JSplitPane.VERTICAL_SPLIT) {
  737.         if(currentLoc == insets.top)
  738.             splitPane.setDividerLocation(splitPane
  739.                          .getLastDividerLocation());
  740.         else
  741.             splitPane.setDividerLocation(splitPane
  742.                          .getHeight() - insets.bottom);
  743.         }
  744.         else {
  745.         if(currentLoc == insets.left)
  746.             splitPane.setDividerLocation(splitPane.
  747.                          getLastDividerLocation());
  748.         else
  749.             splitPane.setDividerLocation(splitPane.
  750.                          getWidth() - insets.right);
  751.         }
  752.     }
  753.     } // End of class BasicSplitPaneDivider.RightActionListener
  754. }
  755.